﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.Practices.EnterpriseLibrary.Data;
using System.Data.Common;
using System.Data;
using System.Reflection;

namespace RioStudio.Website
{
    public class tData
    {
        #region "Declaration"
        private Database _db;
        private static tData _tData;
        private static object syncLock = new object();
        #endregion

        #region "Constructor"

        public tData()
        {
            _db = DatabaseFactory.CreateDatabase();
        }

        #endregion

        #region "Property"

        public static tData Instance
        {
            get
            {
                if (_tData == null)
                {
                    _tData = new tData();
                }

                return _tData;
            }
        }

        #endregion

        #region "Sub/Function"

        private DbCommand CreateCommand<T>(string storedProcedure, T entity) where T : class,new()
        {
            DbCommand comm = _db.GetStoredProcCommand(storedProcedure);

            Type type = entity.GetType();

            _db.DiscoverParameters(comm);

            for (int i = 0; i < comm.Parameters.Count; i++)
            {
                if (comm.Parameters[i].Direction != ParameterDirection.ReturnValue)
                {
                    comm.Parameters[i].Value = type.GetProperty(comm.Parameters[i].ParameterName.Replace("@", "")).GetValue(entity, null);
                }
            }

            return comm;
        }

        public int ExecuteNonQuery<T>(string storedProcedure, T entity) where T : class, new()
        {
            int iResult = _db.ExecuteNonQuery(CreateCommand(storedProcedure, entity));

            return iResult;
        }

        public int ExecuteNonQuery(string storedProcedure, params object[] arrParam)
        {
            return _db.ExecuteNonQuery(storedProcedure, arrParam);
        }

        public List<T> ExecuteReader<T>(string storedProcedure, params object[] arrParam) where T : class,new()
        {
            var reader = _db.ExecuteReader(storedProcedure, arrParam);
            List<T> lstEntity = new List<T>();

            while (reader.Read())
            {
                T entity = new T();
                PropertyInfo[] properties = entity.GetType().GetProperties();

                for (int i = 0; i < properties.Length; i++)
                {
                    PropertyInfo property = properties[i];

                    if (!(reader[property.Name] is DBNull))
                    {
                        property.SetValue(entity, reader[property.Name], null);
                    }
                }

                lstEntity.Add(entity);

            }

            return lstEntity;
        }

        #endregion
    }
}